﻿using AiBLSmartEdu.Module.AIMedicalAssistant.API.Configurations;
using FrameworkCore.DI;
using Microsoft.Extensions.Options;
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace AiBLSmartEdu.Module.AIMedicalAssistant.API.Services;

public class EmbeddingGenerator : IDisposable, ITransientDependency
{
    private readonly HttpClient _httpClient;
    private bool _disposed;

    public EmbeddingGenerator(IOptions<OllamaSettings> options)
    {
        _httpClient = new HttpClient
        {
            BaseAddress = new Uri(options.Value.BaseUrl),
            Timeout = options.Value.Timeout
        };
    }

    public async Task<float[]> GenerateEmbeddingAsync(string text, int dimension)
    {
        if (string.IsNullOrEmpty(text))
            throw new EmbeddingException("输入文本为空");

        try
        {
            var request = new
            {
                model = "all-minilm:l6-v2",
                prompt = text
            };

            var response = await _httpClient.PostAsJsonAsync("/api/embeddings", request);
            response.EnsureSuccessStatusCode();
            var result = await response.Content.ReadFromJsonAsync<OllamaEmbeddingResponse>();
            return result?.Embedding ?? throw new InvalidOperationException("无法解析嵌入响应");
        }
        catch (HttpRequestException ex)
        {
            throw new EmbeddingException($"API请求失败: {ex.Message}");
        }
        catch (JsonException ex)
        {
            throw new EmbeddingException($"响应解析失败： {ex.Message}");
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (_disposed) return;
        if (disposing)
        {
            _httpClient.Dispose();
        }
        _disposed = true;
    }

    private class OllamaEmbeddingResponse
    {
        [JsonPropertyName("embedding")]
        public float[] Embedding { get; set; } = Array.Empty<float>();
    }
}

public class EmbeddingException : Exception
{
    public EmbeddingException(string message) : base(message) { }
}

